mod commands;
mod config;
mod file_system;
use clap::{Arg, ArgAction, Command};
use commands::{check_npx_cli_installed, init_vue_project};
use common::error::with_context;
use common::file_system::deserialize_toml;
use common::model::ProjectConfig;
use common::util::print_err;
use config::{INSTALL_DIR, PACKAGE_INIT_JSON};
use file_system::{create_install_dir, init_dir};
use include_dir::{include_dir, Dir};
use std::fs;
use std::path::Path;

const ASSETS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/assets");
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let matches = Command::new("init vue")
        .version("1.0")
        .author("caozongying<zongying_cao@163.com>")
        .about("caozongying_cao<zongying_cao@163.com> is the author of init_vue")
        .arg(
            Arg::new("config")
                .short('c')
                .long("config")
                .value_name("CONFIG_FILE_PATH")
                .help("配置文件路径")
                .action(ArgAction::Set),
        )
        .get_matches();

    let config_file_path = matches
        .get_one::<String>("config")
        .expect("无法获取config的文件路径");

    let project_config = deserialize_toml::<ProjectConfig>(&fs::read_to_string(config_file_path)?)?;
    let project_name = &project_config.project_name.expect("project_name没有被设置");

    if Path::new(&project_name).exists() {
        println!("项目已经存在，程序终止运行");
        return Ok(());
    }

    check_npx_cli_installed()?;
    init_dir(Path::new(INSTALL_DIR))?;

    // project_dir: 创建的安装项目的路径
    let project_dir = match init_vue_project(
        &create_install_dir().expect("初始化目录失败"),
        project_name,
        ASSETS_DIR
            .get_file(PACKAGE_INIT_JSON)
            .unwrap_or_else(||panic!("获取资源失败，资源名称:{}", PACKAGE_INIT_JSON))
            .contents_utf8()
            .unwrap_or_else(||panic!("读取资源失败，资源名称:{}", PACKAGE_INIT_JSON)),
    ) {
        Ok(result) => result,
        Err(e) => print_err(&e),
    };

    fs::rename(project_dir, project_name).map_err(|err| with_context(err, "main/rename"))?;
    println!("{:?} 创建成功", project_name);
    println!("{}", project_name);
    Ok(())
}
